# Copyright (c) HySoP 2011-2024
#
# This file is part of HySoP software.
# See "https://particle_methods.gricad-pages.univ-grenoble-alpes.fr/hysop-doc/"
# for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from hysop.constants import Implementation
from hysop.fields.continuous_field import Field
from hysop.tools.htypes import check_instance, first_not_None, to_tuple
from hysop.tools.decorators import debug
from hysop.core.graph.computational_node_frontend import ComputationalGraphNodeFrontend
from hysop.topology.cartesian_descriptor import CartesianTopologyDescriptors
from hysop.testsenv import __HAS_OPENCL_BACKEND__
[docs]
class Curl(ComputationalGraphNodeFrontend):
"""Generate an operator to compute the curl of a Field."""
[docs]
@classmethod
def fd(cls, *args, **kwds):
return FiniteDifferencesCurl(*args, **kwds)
[docs]
@classmethod
def spectral(cls, *args, **kwds):
return SpectralCurl(*args, **kwds)
[docs]
@classmethod
def implementations(cls):
raise NotImplementedError
[docs]
@classmethod
def default_implementation(cls):
raise NotImplementedError
@debug
def __new__(cls, Fin, Fout, variables, implementation=None, base_kwds=None, **kwds):
return super().__new__(
cls,
Fin=Fin,
Fout=Fout,
variables=variables,
candidate_input_tensors=None,
candidate_output_tensors=None,
implementation=implementation,
base_kwds=base_kwds,
**kwds,
)
@debug
def __init__(
self, Fin, Fout, variables, implementation=None, base_kwds=None, **kwds
):
"""
Create an operator that computes the curl of an input field Fin.
Given Fin, a 2D ScalarField or VectorField or a 3D VectorField, compute Fout = curl(Fin).
Only the following configurations are supported:
dim nb_components | dim nb_components
Input: 2 (1,2) | 3 3
Output: 2 (2,1) | 3 3
Parameters
----------
Fin: hysop.field.continuous_field.Field
Continuous field as input ScalarField or VectorField.
All contained field have to live on the same domain.
Fout: hysop.field.continuous_field.Field
Continuous field as output VectorField.
All contained field have to live on the same domain.
variables: dict
dictionary of fields as keys and topologies as values.
implementation: Implementation, optional, defaults to None
target implementation, should be contained in available_implementations().
If None, implementation will be set to default_implementation().
kwds: dict, optional
Extra parameters passed towards base class (MultiSpaceDerivatives).
"""
base_kwds = first_not_None(base_kwds, {})
check_instance(Fin, Field)
check_instance(Fout, Field)
check_instance(variables, dict, keys=Field, values=CartesianTopologyDescriptors)
super().__init__(
Fin=Fin,
Fout=Fout,
variables=variables,
candidate_input_tensors=(Fin,),
candidate_output_tensors=(Fout,),
implementation=implementation,
base_kwds=base_kwds,
**kwds,
)
[docs]
class SpectralCurl(Curl):
[docs]
@classmethod
def implementations(cls):
from hysop.backend.host.python.operator.curl import PythonSpectralCurl
__implementations = {
Implementation.PYTHON: PythonSpectralCurl,
}
if __HAS_OPENCL_BACKEND__:
from hysop.backend.device.opencl.operator.curl import OpenClSpectralCurl
__implementations.update(
{
Implementation.OPENCL: OpenClSpectralCurl,
}
)
return __implementations
[docs]
@classmethod
def default_implementation(cls):
return Implementation.PYTHON